package com.fingard.dsp.bank.directbank.weixin01.domain.task;

import com.fingard.dsp.bank.directbank.weixin01.domain.SuccessRateCount;
import com.fingard.dsp.bank.directbank.weixin01.domain.common.DomainConfig;
import com.fingard.dsp.bank.directbank.weixin01.domain.common.DomainConstants;
import com.fingard.dsp.bank.directbank.weixin01.domain.common.DomainUtil;
import com.fingard.dsp.bank.directbank.weixin01.domain.entity.SuccessRateData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 【统计主域名实际请求成功率策略】上报结果分析定时器
 * @author liujinhui
 */
public class SuccessRateCountTimer extends TimerTask {

    private Logger logger = LoggerFactory.getLogger(SuccessRateCountTimer.class);

    private Timer timer;
    private DomainConfig config;
    private SuccessRateCount domainService;
    
    // 每次连续探测次数
    public static final int PROBE_NUM = 5;

    public SuccessRateCountTimer(Timer timer, DomainConfig config,
            SuccessRateCount domainService) {
        this.timer = timer;
        this.config = config;
        this.domainService = domainService;
    }

    @Override
    public void run() {
        if (!domainService.getTimerStatus()) {
            // 关闭定时器
            this.timer.cancel();
        } else {
            String currentDomainMch = domainService.getDomain(DomainConstants.DomainType.API_MCH);
            if (DomainConstants.API_MCH_WEIXIN_DOMAIN.equals(currentDomainMch)) {
                // 微信支付域名请求上报数据统计
                LinkedList<SuccessRateData> dataListMch;
                dataListMch = domainService.getResultData(DomainConstants.DomainType.API_MCH);
                if (dataListMch == null) dataListMch = new LinkedList<SuccessRateData>();
                double rateMch = DomainUtil.computeRate(dataListMch);
                // 通过成功率计算使用主域名还是备用域名
                if (rateMch < (double) config.getReportPassingRate()) {
                    domainService.setDomain(DomainConstants.DomainType.API_MCH, DomainConstants.API_MCH_WEIXIN_RESERVE_DOMAIN);
                    logger.info("【统计主域名实际请求成功率策略】统计域名:"
                            + DomainConstants.API_MCH_WEIXIN_DOMAIN + ";配置成功率:"
                            + config.getReportPassingRate() + ";请求成功率:" + rateMch
                            + ";统计总数:" + dataListMch.size() + ";统计数据:"
                            + dataListMch.toString());
                }
            } else {
                domainDetectionApiMch();
            }
            // 公共平台域名请求上报数据统计
            String currentDomain = domainService.getDomain(DomainConstants.DomainType.API);
            if (DomainConstants.API_WEIXIN_DOMAIN.equals(currentDomain)) {
                LinkedList<SuccessRateData> dataList = 
                        domainService.getResultData(DomainConstants.DomainType.API);
                if (dataList == null) {
                    dataList = new LinkedList<SuccessRateData>();
                }
                double rate = DomainUtil.computeRate(dataList);
                // 通过成功率计算使用主域名还是备用域名
                if (rate < (double) config.getReportPassingRate()) {
                    // 更新当前域名
                    domainService.setDomain(DomainConstants.DomainType.API, currentDomain);
                    logger.info("【统计主域名实际请求成功率策略】统计域名:"
                            + DomainConstants.API_WEIXIN_DOMAIN + ";配置成功率:"
                            + config.getReportPassingRate() + ";请求成功率:" + rate
                            + ";统计总数:" + dataList.size() + ";统计数据:"
                            + dataList.toString());
                }
            }else{
                domainDetectionApi();
            }
        }
    }
    
    /**
     * 探测微信支付主域名连通性，并恢复主域名
     */
    private void domainDetectionApiMch() {
        boolean apiMchBo = true;
        for (int idx = 0; idx < PROBE_NUM; idx++) {
            apiMchBo = DomainUtil.domainLinkTest(DomainConstants.API_MCH_WEIXIN_DOMAIN);
            if (!apiMchBo) {
                break;
            }
        }
        if(apiMchBo){
            // 恢复主域名
            domainService.cleanResultData(DomainConstants.DomainType.API_MCH);
            domainService.setDomain(DomainConstants.DomainType.API_MCH, DomainConstants.API_MCH_WEIXIN_DOMAIN);
            logger.info("【统计主域名实际请求成功率策略】统计域名:"
            +"切换为主域名："+DomainConstants.API_MCH_WEIXIN_DOMAIN);
        }
    }
    
    /**
     * 探测公共平台主域名连通性，并恢复主域名
     */
    private void domainDetectionApi() {
        boolean apiBo = true;
        for (int idx = 0; idx < PROBE_NUM; idx++) {
            apiBo = DomainUtil.domainLinkTest(DomainConstants.API_WEIXIN_DOMAIN);
            if (!apiBo) {
                break; 
            }
        }
        if(apiBo){
            // 恢复主域名
            domainService.cleanResultData(DomainConstants.DomainType.API);
            domainService.setDomain(DomainConstants.DomainType.API, DomainConstants.API_WEIXIN_DOMAIN);
            logger.info("【统计主域名实际请求成功率策略】统计域名:"
                    +"切换为主域名："+DomainConstants.API_WEIXIN_DOMAIN);
        }
    }
}